import smtplib
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
# from src.utils.db_processor import mysql_db_carrier
# import src.utils.report as report
import datetime
import pandas as pd
# from src.utils.config import logger
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
import io


class MailHelper:

    __mail_server = None
    __msg = None
    __sender_address = None
    __receiver_address = None

    def __init__(self, server_type):
        # 初始化邮箱服务器
        self.__mail_server = smtplib.SMTP_SSL(server_type, 465)
        self.__msg = MIMEMultipart()  # 初始化邮件内容主体对象

    def mail_sender_register(self, sender_address, password):
        self.__sender_address = sender_address
        self.__mail_server.login(sender_address, password)  # 发送人邮箱 授权码

    def msg_sender_name(self, sender_name="默认发件人名称"):
        self.__msg["From"] = sender_name + "<" + self.__sender_address + ">"

    def mail_receiver_address(self, receiver_address):
        self.__receiver_address = receiver_address.split(",")
        self.__msg["To"] = ','.join(self.__receiver_address)

    def msg_title(self, title):
        self.__msg["Subject"] = title

    def msg_content(self, content):
        self.__msg.attach(MIMEText(content, "html", "utf-8"))

    def msg_image(self, image_id, image_name, image):
        self.msg_content(
            '<div align="center"><p><img src="cid:image_{0}" alt="image_{0}"></p></div>'.format(image_id))  # 邮件内容
        image.add_header('Content-ID', 'image_{0}'.format(image_id))
        self.__msg.attach(image)

    def msg_attach(self, file_paths):
        file_paths = file_paths.split(",")
        for file_path in file_paths:
            file_name = file_path.split("/")[-1]
            file = MIMEApplication(open(file_path, 'rb').read())
            file.add_header('Content-Disposition', 'attachment', filename=file_name)  # 设置附件信息
            self.__msg.attach(file)

    def send(self):
        self.__mail_server.sendmail(self.__sender_address, self.__receiver_address, self.__msg.as_string())
        self.__mail_server.quit()


def run_image(receiver_address='hongwei.shen@atrenew.com', mail_title=str(datetime.datetime.now().strftime('%Y_%m_%d')),
              font_path='../../data/font/simhei.ttf', run_date=str(datetime.date.today())):
    try:

        mail = MailHelper("smtp.feishu.cn")  # 邮箱服务器类型
        mail.mail_sender_register("hongwei.shen@atrenew.com", "XXXXXXXXXX")  # 发件人邮箱 授权码
        mail.msg_sender_name("沈红伟")  # 发件人姓名
        mail.mail_receiver_address(receiver_address)  # 收件人账号，为多个时英文逗号隔开

        mail.msg_title("手机价格竞争力对比_人工vs算法_{}".format(mail_title))  # 邮件标题

        fm.fontManager.addfont(path=font_path)
        prop = fm.FontProperties(fname=font_path)

        plt.rcParams['font.sans-serif'] = prop.get_name()  # 设置中文字体为黑体
        plt.rcParams['axes.unicode_minus'] = False  # 解决保存图像是负号'-'显示为方块的问题

        df_info = mysql_db_carrier.load_sql('''
        select 
            * 
        from 
            tabke_ds 
        where 
            logistics_complete_date 
                between 
                    date_add(date('{0}') ,INTERVAL -30 day)
                and
                    date_add(date('{0}') ,INTERVAL -1 day)
        '''.format(run_date))
        df_info = df_info.sort_values(by=['operational_centre_name_rk', 'logistics_complete_date'],
                                      ascending=[True, False])
        df_info = df_info.reset_index(drop=True)

        for k1, v1 in df_info.groupby(['operational_centre_name_rk', 'operational_centre_name']):

            plt.figure(figsize=(18, 6))

            y_min, y_max = 10, 0
            for k2, v2 in v1.groupby(['model_type', 'indicator_key']):
                v = v2.sort_values(by=['logistics_complete_date'], ascending=[False])
                # x轴数据
                x = v['logistics_complete_date'].to_list()
                # y轴数据
                y = v['indicator_value'].to_list()

                line_style = '-'
                if '预估' in k2[1]:
                    line_style = '--'

                if k2[0] == '线上模型':
                    plt.plot(x[:30], y[:30], linestyle=line_style, marker='+',
                             label='{}【{}】'.format(k2[1], k2[0]))  # 绘制折线图
                elif k2[0] == '当日模型':
                    plt.plot(x[:30], y[:30], linestyle=line_style, marker='x',
                             label='{}【{}】'.format(k2[1], k2[0]))  # 绘制折线图
                elif k2[0] == '每日模型':
                    plt.scatter(x[:14], y[:14], linestyle=line_style, marker='o',
                                label='{}【{}】'.format(k2[1], k2[0]))  # 绘制散点图

                y_min = min(y_min, min([item for item in y if item > 0]))
                y_max = max(y_max, max([item for item in y if item > 0]))
            plt.title(k1[1])  # 设置标题
            plt.legend(loc='upper left')
            plt.xticks(rotation=30)  # 横坐标
            plt.ylim(y_min, y_max)

            # plt.xlabel('X-axis')  # 设置x轴标签
            # plt.ylabel('Y-axis')  # 设置y轴标签

            buf = io.BytesIO()
            plt.savefig(buf, format='png')
            mail.msg_image(k1[0], k1[1], MIMEImage(buf.getvalue()))
            # mail.msg_attach('{}'.format(file_name))  # 邮件附件，传入附件路径，路径多个时英文逗号隔离
            v = v1[v1['logistics_complete_date'] >= (report.str2date(run_date) - datetime.timedelta(days=30)).date()]
            v = v[v['logistics_complete_date'] <= (report.str2date(run_date) - datetime.timedelta(days=1)).date()]
            v = v[['model_type', 'indicator_key', 'logistics_complete_date', 'indicator_value']]

            df_tmp = pd.merge(v[(v['model_type'] == '线上模型') & (v['indicator_key'] == '预估单定单费用')][
                                  ['logistics_complete_date', 'indicator_value']],
                              v[(v['model_type'] == '每日模型') & (v['indicator_key'] == '预估单定单费用')][
                                  ['logistics_complete_date', 'indicator_value']],
                              how='inner', on='logistics_complete_date', suffixes=("_online", "_offline"))

            df_tmp['model_type'] = '每日模型'
            df_tmp['indicator_key'] = '预估单定单较线上比例'
            df_tmp['indicator_value'] = (df_tmp['indicator_value_offline'] / df_tmp['indicator_value_online'])
            df_tmp['indicator_value'] = round(df_tmp['indicator_value'], 3)

            v = pd.concat([v[['model_type', 'indicator_key', 'logistics_complete_date', 'indicator_value']],
                           df_tmp[['model_type', 'indicator_key', 'logistics_complete_date', 'indicator_value']]])
            v['indicator_value'] = round(v['indicator_value'], 3)

            v = v.pivot_table(index=['model_type', 'indicator_key'],
                              columns='logistics_complete_date',
                              values=['indicator_value'],
                              aggfunc=lambda x: x)
            v.columns = [str(s2) for (s1, s2) in list(v.columns)]
            v = v.sort_index(axis=1, ascending=False)
            v = v.sort_values(by=['model_type', 'indicator_key'], ascending=[False, True])

            mail.msg_content('<div align="center"><p>{}</p></div>'.format(v.to_html()))  # 邮件内容

            df_tmp = df_tmp[df_tmp['logistics_complete_date'] >= (report.str2date(run_date) - datetime.timedelta(days=5)).date()]
            cnt = df_tmp[df_tmp['indicator_value'] < 1].shape[0]
            mail.msg_content('<div align="center"><p style="color:red"><b>近5天预估单定单降低{}次</b></p></div>'.format(cnt))  # 邮件内容

            mail.msg_content('<br></br>')  # 邮件内容

        mail.send()
        logger.info('mail send success')


    except Exception as e:
        logger.error(str(e))
        exit(1)
